﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using Microsoft.WindowsAzure.ServiceRuntime;
using SqlShareAPI;

namespace WebQueryRole
{
    public class WebAuthentication
    {

        /// <summary>
        /// Another login method for calling from generic HTTP handlers (indpendent services processing HTTP reqs)
        /// </summary>
        /// <param name="context"></param>
        /// <param name="factory"></param>
        /// <param name="redirect"></param>
        /// <returns></returns>
        public static UserSession IsLoggedIn(HttpContext context, SSAPIFactory factory, bool redirect)
        {
            return IsLoggedIn(context.Request, context.Response, factory, redirect);
        }
        
        /// <summary>
        /// attempt to login into a user, if failed return null, if redirect true then redirect page to login
        /// </summary>
        /// <param name="page"></param>
        /// <param name="factory"></param>
        /// <param name="redirect"></param>
        /// <returns></returns>
        protected static UserSession IsLoggedIn(HttpRequest request, HttpResponse response, SSAPIFactory factory, bool redirect)
        {                        
            // if we are in test environment and not deployed, skip login step
            /*
            if (!RoleEnvironment.IsAvailable)
            {
                return LoginState.UNKNOWN_USER;
            }
            */

            if (    request.Cookies["session"] == null ||
                    string.IsNullOrEmpty(request.Cookies["session"]["username"]) ||
                    string.IsNullOrEmpty(request.Cookies["session"]["token"]))
            {
                if (redirect)
                {
                    RedirectLogin(request, response);
                }
                return null;
            }
            string username = request.Cookies["session"]["username"];
            string token = request.Cookies["session"]["token"];

            SSAuthentication auth = factory.CreateAuthentication(username);
            if (!auth.AuthenticateToken(token) && redirect)
            {                
                RedirectLogin(request, response);
                return null;
            }

            return auth.GetUserSession();
        }        

        /// <summary>
        /// This method pulls out cookies that belong to the user and attempts
        /// to see if these cookies belong to an existing session in the database.
        /// IF IT DOES NOT, it will be redirected to the login page.
        /// </summary>
        /// <param name="page"></param>
        /// <param name="factory"></param>
        /// <returns></returns>
        public static UserSession IsLoggedIn(Page page, SSAPIFactory factory)
        {
            return IsLoggedIn(page.Request, page.Response, factory, true);
        }

        public static UserSession IsLoggedIn(MasterPage page, SSAPIFactory factory)
        {
            return IsLoggedIn(page.Request, page.Response, factory, true);
        }

        private static void RedirectLogin(HttpRequest request, HttpResponse response)
        {
            // if we are not at the page
            if (!request.Url.ToString().Contains("login.aspx"))
            {
                response.BufferOutput = true;
                response.Redirect("login.aspx?url=" + request.Url.Segments[1]);
            }
        }

        /// <summary>
        /// Attempt to log in, if login fails, this method will redirect the user's browser to the login page
        /// and return false.
        /// </summary>
        /// <param name="username"></param>
        /// <param name="password"></param>
        /// <param name="dbCollection"></param>
        /// <returns></returns>
        public static UserSession LogIn(Page page, string username, string password, SSAPIFactory factory)
        {            
            SSAuthentication auth = factory.CreateAuthentication(username);
            if (!auth.AuthenticatePassword(password))
            {
                return null;
            }

            UserSession session = auth.GetUserSession();

            page.Response.Cookies["session"]["username"] = username;
            page.Response.Cookies["session"]["token"] = session.Token;

            return session;
        }

        public static void LogOut(Page page, UserSession userSession)
        {
            page.Response.Cookies["session"]["username"] = string.Empty;
            page.Response.Cookies["session"]["token"] = string.Empty;
        }
    }
}